/*
 * Copyright [2022] [https://www.xiaonuo.vip]
 *
 * Snowy采用APACHE LICENSE 2.0开源协议，您在使用过程中，需要注意以下几点：
 *
 * 1.请不要删除和修改根目录下的LICENSE文件。
 * 2.请不要删除和修改Snowy源码头部的版权声明。
 * 3.本项目代码可免费商业使用，商业使用请保留源码和相关描述文件的项目出处，作者声明等。
 * 4.分发源码时候，请注明软件出处 https://www.xiaonuo.vip
 * 5.不可二次分发开源参与同类竞品，如有想法可联系团队xiaonuobase@qq.com商议合作。
 * 6.若您的项目无法满足以上几点，需要更多功能代码，获取Snowy商业授权许可，请在官网购买授权，地址为 https://www.xiaonuo.vip
 */
package com.xieq.dota.modular.matchplayer.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.collection.CollStreamUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xieq.dota.modular.matchplayer.entity.MatchPlayer;
import com.xieq.dota.modular.matchplayer.entity.MatchPlayerPage;
import com.xieq.dota.modular.matchplayer.mapper.MatchPlayerMapper;
import com.xieq.dota.modular.matchplayer.param.MatchPlayerAddParam;
import com.xieq.dota.modular.matchplayer.param.MatchPlayerEditParam;
import com.xieq.dota.modular.matchplayer.param.MatchPlayerIdParam;
import com.xieq.dota.modular.matchplayer.param.MatchPlayerPageParam;
import com.xieq.dota.modular.matchplayer.service.MatchPlayerService;
import com.xieq.dota.modular.player.entity.Player;
import com.xieq.dota.modular.player.service.PlayerService;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import vip.xiaonuo.auth.core.util.StpLoginUserUtil;
import vip.xiaonuo.common.enums.CommonSortOrderEnum;
import vip.xiaonuo.common.exception.CommonException;
import vip.xiaonuo.common.page.CommonPageRequest;
import java.math.BigDecimal;
import java.util.Date;

import vip.xiaonuo.common.util.CommonDownloadUtil;
import vip.xiaonuo.common.util.CommonResponseUtil;

import java.io.File;
import java.io.IOException;
import java.util.List;

/**
 * 比赛选手表Service接口实现类
 *
 * @author xieq
 * @date  2025/11/06 11:17
 **/
@Service
public class MatchPlayerServiceImpl extends ServiceImpl<MatchPlayerMapper, MatchPlayer> implements MatchPlayerService {

    @Autowired
    private PlayerService playerService;

    @Override
    public IPage<MatchPlayerPage> page(MatchPlayerPageParam matchPlayerPageParam) {
        QueryWrapper<MatchPlayer> queryWrapper = new QueryWrapper<MatchPlayer>().checkSqlInjection();
        if(ObjectUtil.isAllNotEmpty(matchPlayerPageParam.getSortField(), matchPlayerPageParam.getSortOrder())) {
            CommonSortOrderEnum.validate(matchPlayerPageParam.getSortOrder());
            queryWrapper.orderBy(true, matchPlayerPageParam.getSortOrder().equals(CommonSortOrderEnum.ASC.getValue()),
                    StrUtil.toUnderlineCase(matchPlayerPageParam.getSortField()));
        } else {
            queryWrapper.lambda().orderByAsc(MatchPlayer::getId);
        }
        Page<MatchPlayer> page = this.page(CommonPageRequest.defaultPage(), queryWrapper);
        return page.convert(item -> {
            MatchPlayerPage matchPlayerPage = new MatchPlayerPage();
            BeanUtil.copyProperties(item, matchPlayerPage);
            Player player = playerService.lambdaQuery().eq(Player::getAccount, item.getPlayId()).one();
            matchPlayerPage.setPlayName(player.getNickname());
            matchPlayerPage.setAbility(player.getAbility());
            matchPlayerPage.setPositions(player.getPositions());
            matchPlayerPage.setMmr(player.getMmr());
            return matchPlayerPage;
        });

    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void add(MatchPlayerAddParam matchPlayerAddParam) {

        MatchPlayer matchPlayer = BeanUtil.toBean(matchPlayerAddParam, MatchPlayer.class);
        String account = StpLoginUserUtil.getLoginUser().getAccount();
        Player player = playerService.lambdaQuery().eq(Player::getAccount, account).one();
        if(ObjectUtil.isEmpty(player)) {
            throw new CommonException("选手不存在，playId值为：{}, 联系管理员添加", account);
        }
        matchPlayer.setPlayId(account);

        MatchPlayer one = this.lambdaQuery().eq(MatchPlayer::getMatchId, matchPlayer.getMatchId())
                .eq(MatchPlayer::getPlayId, matchPlayer.getPlayId())
                .one();
        if(ObjectUtil.isNotEmpty(one)) {
            throw new CommonException("你已经报名，请不要重复报名", matchPlayer.getId());
        }

        this.save(matchPlayer);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void edit(MatchPlayerEditParam matchPlayerEditParam) {
        MatchPlayer matchPlayer = this.queryEntity(matchPlayerEditParam.getId());
        BeanUtil.copyProperties(matchPlayerEditParam, matchPlayer);
        this.updateById(matchPlayer);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void delete(List<MatchPlayerIdParam> matchPlayerIdParamList) {
        // 执行删除
        this.removeByIds(CollStreamUtil.toList(matchPlayerIdParamList, MatchPlayerIdParam::getId));
    }

    @Override
    public MatchPlayer detail(MatchPlayerIdParam matchPlayerIdParam) {
        return this.queryEntity(matchPlayerIdParam.getId());
    }

    @Override
    public MatchPlayer queryEntity(String id) {
        MatchPlayer matchPlayer = this.getById(id);
        if(ObjectUtil.isEmpty(matchPlayer)) {
            throw new CommonException("比赛选手表不存在，id值为：{}", id);
        }
        return matchPlayer;
    }

    @Override
    public void downloadImportTemplate(HttpServletResponse response) throws IOException {
       File tempFile = null;
       try {
         List<MatchPlayerEditParam> dataList = CollectionUtil.newArrayList();
         String fileName = "比赛选手表导入模板_" + DateUtil.format(DateTime.now(), DatePattern.PURE_DATETIME_PATTERN) + ".xlsx";
         tempFile = FileUtil.file(FileUtil.getTmpDir() + FileUtil.FILE_SEPARATOR + fileName);
         EasyExcel.write(tempFile.getPath(), MatchPlayerEditParam.class).sheet("比赛选手表").doWrite(dataList);
         CommonDownloadUtil.download(tempFile, response);
       } catch (Exception e) {
         log.error(">>> 比赛选手表导入模板下载失败：", e);
         CommonResponseUtil.renderError(response, "比赛选手表导入模板下载失败");
       } finally {
         FileUtil.del(tempFile);
       }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public JSONObject importData(MultipartFile file) {
        try {
            int successCount = 0;
            int errorCount = 0;
            JSONArray errorDetail = JSONUtil.createArray();
            // 创建临时文件
            File tempFile = FileUtil.writeBytes(file.getBytes(), FileUtil.file(FileUtil.getTmpDir() +
                    FileUtil.FILE_SEPARATOR + "matchPlayerImportTemplate.xlsx"));
            // 读取excel
            List<MatchPlayerEditParam> matchPlayerEditParamList =  EasyExcel.read(tempFile).head(MatchPlayerEditParam.class).sheet()
                    .headRowNumber(1).doReadSync();
            List<MatchPlayer> allDataList = this.list();
            for (int i = 0; i < matchPlayerEditParamList.size(); i++) {
                JSONObject jsonObject = this.doImport(allDataList, matchPlayerEditParamList.get(i), i);
                if(jsonObject.getBool("success")) {
                    successCount += 1;
                } else {
                    errorCount += 1;
                    errorDetail.add(jsonObject);
                }
            }
            return JSONUtil.createObj()
                    .set("totalCount", matchPlayerEditParamList.size())
                    .set("successCount", successCount)
                    .set("errorCount", errorCount)
                    .set("errorDetail", errorDetail);
        } catch (Exception e) {
            log.error(">>> 比赛选手表导入失败：", e);
            throw new CommonException("比赛选手表导入失败");
        }
    }

    public JSONObject doImport(List<MatchPlayer> allDataList, MatchPlayerEditParam matchPlayerEditParam, int i) {
        String id = matchPlayerEditParam.getId();
        if(ObjectUtil.hasEmpty(id)) {
            return JSONUtil.createObj().set("index", i + 1).set("success", false).set("msg", "必填字段存在空值");
        } else {
            try {
                int index = CollStreamUtil.toList(allDataList, MatchPlayer::getId).indexOf(matchPlayerEditParam.getId());
                MatchPlayer matchPlayer;
                boolean isAdd = false;
                if(index == -1) {
                    isAdd = true;
                    matchPlayer = new MatchPlayer();
                } else {
                    matchPlayer = allDataList.get(index);
                }
                BeanUtil.copyProperties(matchPlayerEditParam, matchPlayer);
                if(isAdd) {
                    allDataList.add(matchPlayer);
                } else {
                    allDataList.remove(index);
                    allDataList.add(index, matchPlayer);
                }
                this.saveOrUpdate(matchPlayer);
                return JSONUtil.createObj().set("success", true);
            } catch (Exception e) {
              log.error(">>> 数据导入异常：", e);
              return JSONUtil.createObj().set("success", false).set("index", i + 1).set("msg", "数据导入异常");
            }
        }
    }

    @Override
    public void exportData(List<MatchPlayerIdParam> matchPlayerIdParamList, HttpServletResponse response) throws IOException {
       File tempFile = null;
       try {
         List<MatchPlayerEditParam> dataList;
         if(ObjectUtil.isNotEmpty(matchPlayerIdParamList)) {
            List<String> idList = CollStreamUtil.toList(matchPlayerIdParamList, MatchPlayerIdParam::getId);
            dataList = BeanUtil.copyToList(this.listByIds(idList), MatchPlayerEditParam.class);
         } else {
            dataList = BeanUtil.copyToList(this.list(), MatchPlayerEditParam.class);
         }
         String fileName = "比赛选手表_" + DateUtil.format(DateTime.now(), DatePattern.PURE_DATETIME_PATTERN) + ".xlsx";
         tempFile = FileUtil.file(FileUtil.getTmpDir() + FileUtil.FILE_SEPARATOR + fileName);
         EasyExcel.write(tempFile.getPath(), MatchPlayerEditParam.class).sheet("比赛选手表").doWrite(dataList);
         CommonDownloadUtil.download(tempFile, response);
       } catch (Exception e) {
         log.error(">>> 比赛选手表导出失败：", e);
         CommonResponseUtil.renderError(response, "比赛选手表导出失败");
       } finally {
         FileUtil.del(tempFile);
       }
    }
}
